<template>
  <div class="app">
    <h1>可穿戴设备数据可视化平台</h1>
    <div class="dashboard">
      <div class="chart-container">
        <h2>心率数据（实时推送）</h2>
        <div ref="heartRateChart" class="chart"></div>
        <div v-if="anomaly" class="anomaly-alert">{{ anomaly }}</div>
      </div>
      <div class="chart-container">
        <h2>步数数据（实时推送）</h2>
        <div ref="stepsChart" class="chart"></div>
      </div>
      <div class="chart-container">
        <h2>睡眠时长（实时推送）</h2>
        <div ref="sleepChart" class="chart"></div>
      </div>
      <div class="chart-container">
        <h2>睡眠阶段分布（实时推送）</h2>
        <div ref="sleepStageChart" class="chart"></div>
      </div>
    </div>
    <div class="history-query">
      <h2>历史数据查询</h2>
      <label>设备ID: <input v-model="queryDeviceId" /></label>
      <label>开始时间: <input type="datetime-local" v-model="queryStart" /></label>
      <label>结束时间: <input type="datetime-local" v-model="queryEnd" /></label>
      <button @click="fetchHistory">查询</button>
      <div ref="historyChart" class="chart" style="margin-top:20px"></div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue'
import * as echarts from 'echarts'
import SockJS from 'sockjs-client'
import Stomp from 'stompjs'
import axios from 'axios'

const heartRateChart = ref(null)
const stepsChart = ref(null)
const sleepChart = ref(null)
const sleepStageChart = ref(null)
const historyChart = ref(null)

let heartRateInstance = null
let stepsInstance = null
let sleepInstance = null
let sleepStageInstance = null
let historyInstance = null
let stompClient = null

let heartRateData = []
let heartRateTime = []
let stepsData = []
let stepsTime = []
let sleepData = []
let sleepTime = []

const anomaly = ref(null)

// 睡眠阶段数据
const sleepStageTime = ref([])
const sleepStageSeries = ref({
  "深睡": [],
  "浅睡": [],
  "快速眼动": [],
  "清醒": []
})
const sleepStageColors = {
  "深睡": '#6c63ff',
  "浅睡": '#b388ff',
  "快速眼动": '#ff8fa3',
  "清醒": '#ffd166'
}

function initCharts() {
  heartRateInstance = echarts.init(heartRateChart.value)
  stepsInstance = echarts.init(stepsChart.value)
  sleepInstance = echarts.init(sleepChart.value)
  sleepStageInstance = echarts.init(sleepStageChart.value)
  heartRateInstance.setOption(getOption('心率', heartRateTime, heartRateData))
  stepsInstance.setOption(getOption('步数', stepsTime, stepsData))
  sleepInstance.setOption(getOption('睡眠时长', sleepTime, sleepData))
  sleepStageInstance.setOption(getSleepStageOption())
}

function getOption(name, xData, yData) {
  return {
    title: { text: name },
    tooltip: { trigger: 'axis' },
    xAxis: {
      type: 'category',
      data: xData,
      name: '时间',
      axisLabel: { formatter: value => value.slice(11, 19) }
    },
    yAxis: { type: 'value', name },
    series: [{ type: 'line', data: yData, smooth: true }]
  }
}

function getSleepStageOption() {
  return {
    title: { text: '睡眠阶段分布' },
    tooltip: { trigger: 'axis' },
    legend: { data: Object.keys(sleepStageSeries.value) },
    xAxis: {
      type: 'category',
      data: sleepStageTime.value,
      name: '小时',
      axisLabel: { formatter: value => value.slice(11, 16) }
    },
    yAxis: {
      type: 'category',
      data: ['深睡', '浅睡', '快速眼动', '清醒'],
      name: '阶段',
      axisLabel: { formatter: value => value }
    },
    series: Object.keys(sleepStageSeries.value).map(stage => ({
      name: stage,
      type: 'bar',
      stack: 'sleep',
      barWidth: '60%',
      itemStyle: { color: sleepStageColors[stage] },
      data: sleepStageSeries.value[stage]
    }))
  }
}

function updateChart(chart, xArr, yArr, newTime, newValue) {
  xArr.push(newTime)
  yArr.push(newValue)
  if (xArr.length > 30) {
    xArr.shift()
    yArr.shift()
  }
  chart.setOption({
    xAxis: { data: xArr },
    series: [{ data: yArr }]
  })
}

function updateSleepStage(newTime, newStage) {
  sleepStageTime.value.push(newTime)
  Object.keys(sleepStageSeries.value).forEach(stage => {
    sleepStageSeries.value[stage].push(stage === newStage ? 1 : 0)
    if (sleepStageSeries.value[stage].length > 30) {
      sleepStageSeries.value[stage].shift()
    }
  })
  if (sleepStageTime.value.length > 30) sleepStageTime.value.shift()
  sleepStageInstance.setOption(getSleepStageOption())
}

function connectWebSocket() {
  const socket = new SockJS('http://localhost:8080/ws')
  stompClient = Stomp.over(socket)
  stompClient.connect({}, () => {
    stompClient.subscribe('/topic/wearable-data', (message) => {
      const data = JSON.parse(message.body)
      if (data.heartRate && data.timestamp) {
        updateChart(heartRateInstance, heartRateTime, heartRateData, data.timestamp, data.heartRate)
      }
      if (data.steps && data.timestamp) {
        updateChart(stepsInstance, stepsTime, stepsData, data.timestamp, data.steps)
      }
      if (data.sleepDuration && data.timestamp) {
        updateChart(sleepInstance, sleepTime, sleepData, data.timestamp, data.sleepDuration)
      }
      if (data.isAnomaly && data.anomalyDescription) {
        anomaly.value = `异常告警：${data.anomalyDescription}（${data.timestamp.slice(11,19)}）`
        setTimeout(() => { anomaly.value = null }, 5000)
      }
    })
    stompClient.subscribe('/topic/sleep-stage', (message) => {
      const data = JSON.parse(message.body)
      if (data.sleepStage && data.timestamp) {
        updateSleepStage(data.timestamp, data.sleepStage)
      }
    })
  })
}

// 历史数据查询
const queryDeviceId = ref('device_normal')
const queryStart = ref('')
const queryEnd = ref('')

async function fetchHistory() {
  if (!queryDeviceId.value || !queryStart.value || !queryEnd.value) {
    alert('请填写完整查询条件')
    return
  }
  const url = `/api/wearable/data?deviceId=${queryDeviceId.value}&start=${new Date(queryStart.value).toISOString()}&end=${new Date(queryEnd.value).toISOString()}`
  const res = await axios.get(url)
  const data = res.data
  const xData = data.map(item => item.timestamp)
  const yData = data.map(item => item.heartRate)
  await nextTick()
  if (!historyInstance) historyInstance = echarts.init(historyChart.value)
  historyInstance.setOption(getOption('历史心率', xData, yData))
}

onMounted(async () => {
  await nextTick()
  initCharts()
  connectWebSocket()
})

onUnmounted(() => {
  if (stompClient) stompClient.disconnect()
  if (heartRateInstance) heartRateInstance.dispose()
  if (stepsInstance) stepsInstance.dispose()
  if (sleepInstance) sleepInstance.dispose()
  if (sleepStageInstance) sleepStageInstance.dispose()
  if (historyInstance) historyInstance.dispose()
})
</script>

<style>
.app {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}
.dashboard {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  margin-top: 20px;
}
.chart-container {
  flex: 1 1 300px;
  min-width: 300px;
}
.chart {
  width: 100%;
  height: 300px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}
.anomaly-alert {
  color: #fff;
  background: #e74c3c;
  padding: 8px 16px;
  border-radius: 6px;
  margin-top: 10px;
  font-weight: bold;
  display: inline-block;
}
.history-query {
  margin-top: 40px;
  background: #fff;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}
.history-query label {
  margin-right: 20px;
}
</style>